home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / GDIDIB.PAK / PALCTRL.C < prev    next >
C/C++ Source or Header  |  1997-05-06  |  24KB  |  854 lines

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright (C) 1993 - 1995  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE:   palctrl.c
  9. //
  10. //  PURPOSE:  Implement the window procedure for the palette control
  11. //            window.
  12. //
  13. //  FUNCTIONS:
  14. //    RegisterPalCtrlClass    - Registers the PalCtrl window class.
  15. //    PalCtrlProc             - Processes messages for the main window.
  16. //    MsgPalCtrlCommand       - Handle the WM_COMMAND messages for the window.
  17. //    MsgPalCtrlPaint         - Handles the WM_PAINT messages.
  18. //    MsgPalCtrlLButtonDown   - Handles the WM_LBUTTONDOWN messages.
  19. //    MsgPalCtrlLButtonDblClk - Handles the WM_LBUTTONDBLCLK messages.
  20. //    MsgPalCtrlGetDlgCode    - Handles the WM_GETDLGCODE message.
  21. //    MsgPalCtrlKeyDown       - Handles the WMKEYDOWN messages.
  22. //    MsgPalCtrlDestroy       - Handles the WM_DESTROY message by calling 
  23. //                              PostQuitMessage().
  24. //    MsgPalCtrlGetCurSel     - Handles the PCM_GETCURSEL messages.
  25. //    MsgPalCtrlSetCurSel     - Handles the PCM_SETCURSEL messages.
  26. //    HighlightSquare         - Highlights a color square on the PalCtrl.
  27. //    UnHighlightSquare       - Unhighlights a color square on the PalCtrl.
  28. //    SetPalCtrlPalette       - Sets the palette to be displayed in the
  29. //                              PalCtrl window.
  30. //
  31. //  COMMENTS:
  32. //
  33.  
  34. #include <windows.h>            // required for all Windows applications
  35. #include <windowsx.h>
  36. #include "globals.h"            // prototypes specific to this application
  37. #include "palette.h"
  38. #include "palctrl.h"
  39.  
  40.  
  41. // globals
  42. PALINFO palinfo;
  43.  
  44.  
  45. // Palette control message table definition.
  46. MSD rgmsdPalCtrl[] =
  47. {
  48.     {WM_CREATE,        MsgPalCtrlCreate},
  49.     {WM_PAINT,         MsgPalCtrlPaint},
  50.     {WM_LBUTTONDOWN,   MsgPalCtrlLButtonDown},
  51.     {WM_LBUTTONDBLCLK, MsgPalCtrlLButtonDblClk},
  52.     {WM_DESTROY,       MsgPalCtrlDestroy},
  53.     {WM_GETDLGCODE,    MsgPalCtrlGetDlgCode},
  54.     {WM_KEYDOWN,       MsgPalCtrlKeyDown},
  55.  
  56.     // PalCtrl interface messages
  57.     {PCM_GETCURSEL,    MsgPalCtrlGetCurSel},
  58.     {PCM_SETCURSEL,    MsgPalCtrlSetCurSel}
  59. };
  60.  
  61. MSDI msdiPalCtrl =
  62. {
  63.     sizeof(rgmsdPalCtrl) / sizeof(MSD),
  64.     rgmsdPalCtrl,
  65.     edwpWindow
  66. };
  67.  
  68.  
  69. //
  70. //  FUNCTION: RegisterPalCtrlClass(HINSTANCE)
  71. //
  72. //  PURPOSE:  Registers the palette control window class.
  73. //
  74. //  PARAMETERS:
  75. //
  76. //    hInstance - instance that owns this class
  77. //
  78. //  RETURN VALUE:
  79. //
  80. //    TRUE for success, FALSE otherwise
  81. //
  82. //  COMMENTS:
  83. //
  84.  
  85. BOOL RegisterPalCtrlClass(HINSTANCE hInstance)
  86. {
  87.     WNDCLASS wc;
  88.  
  89.     // Fill in window class structure with parameters that describe the
  90.     // palette control window.
  91.  
  92.     wc.style         = CS_DBLCLKS;              // Class style(s).
  93.     wc.lpfnWndProc   = (WNDPROC)PalCtrlProc;    // Window Procedure
  94.     wc.cbClsExtra    = 0;                       // No per-class extra data.
  95.     wc.cbWndExtra    = PAL_CBWNDEXTRA;          // Per-window extra data.
  96.     wc.hInstance     = hInstance;               // Owner of this class
  97.     wc.hIcon         = NULL;                    // Icon name from .RC
  98.     wc.hCursor       = LoadCursor(NULL, IDC_ARROW); // Cursor
  99.     wc.hbrBackground = GetStockObject(NULL_BRUSH); // Default color
  100.     wc.lpszMenuName  = NULL;                    // Menu name from .RC
  101.     wc.lpszClassName = "PalCtrlClass";          // Name to register as
  102.  
  103.     // Register the window class
  104.     return RegisterClass(&wc);
  105. }
  106.  
  107.  
  108. //
  109. //  FUNCTION: PalCtrlProc(HWND, UINT, WPARAM, LPARAM)
  110. //
  111. //  PURPOSE:  Processes messages for the main window.
  112. //
  113. //  PARAMETERS:
  114. //    hwnd     - window handle
  115. //    uMessage - message number
  116. //    wparam   - additional information (dependant on message number)
  117. //    lparam   - additional information (dependant on message number)
  118. //
  119. //  RETURN VALUE:
  120. //    The return value depends on the message number.  If the message
  121. //    is implemented in the message dispatch table, the return value is
  122. //    the value returned by the message handling function.  Otherwise,
  123. //    the return value is the value returned by the default window procedure.
  124. //
  125. //  COMMENTS:
  126. //    Call the DispMessage() function with the main window's message dispatch
  127. //    information (msdiPalCtrl) and the message specific information.
  128. //
  129.  
  130. LRESULT CALLBACK PalCtrlProc(HWND   hwnd, 
  131.                              UINT   uMessage, 
  132.                              WPARAM wparam, 
  133.                              LPARAM lparam)
  134. {
  135.     return DispMessage(&msdiPalCtrl, hwnd, uMessage, wparam, lparam);
  136. }
  137.  
  138.  
  139. //
  140. //  FUNCTION: MsgPalCtrlCreate(HWND, UINT, WPARAM, LPARAM)
  141. //
  142. //  PURPOSE: 
  143. //
  144. //  PARAMETERS:
  145. //
  146. //    hwnd      - Window handle  (Unused)
  147. //    uMessage  - Message number (Unused)
  148. //    wparam    - Extra data     (Unused)
  149. //    lparam    - Extra data     (Unused)
  150. //
  151. //  RETURN VALUE:
  152. //
  153. //    Always returns 0 - Message handled
  154. //
  155. //  COMMENTS:
  156. //
  157.  
  158. #pragma argsused
  159. LRESULT MsgPalCtrlCreate(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  160. {
  161.     HANDLE hPalCtrlInfo;
  162.  
  163.     hPalCtrlInfo = GlobalAlloc(GHND, sizeof(PALCTRLINFO));
  164.     if (hPalCtrlInfo)
  165.     {
  166.         RECT          rect;
  167.         LPPALCTRLINFO lpPalCtrlInfo;
  168.  
  169.         GetClientRect(hwnd, &rect);
  170.  
  171.         lpPalCtrlInfo              = (LPPALCTRLINFO)GlobalLock(hPalCtrlInfo);
  172.         lpPalCtrlInfo->hPal        = NULL;
  173.         lpPalCtrlInfo->nEntries    = 0;
  174.         lpPalCtrlInfo->nRows       = 16;
  175.         lpPalCtrlInfo->nCols       = 16;
  176.         lpPalCtrlInfo->cxSquare    = (rect.right - rect.left) / 16;
  177.         lpPalCtrlInfo->cySquare    = (rect.bottom - rect.top) / 16;
  178.         lpPalCtrlInfo->nEntry      = 0;
  179.  
  180.         GlobalUnlock(hPalCtrlInfo);
  181.     }
  182.  
  183.     SetWindowLong(hwnd, WL_PAL_HPALCTRLINFO, (LONG)hPalCtrlInfo);
  184.  
  185.     SetPalCtrlPalette(hwnd, GetSystemPalette());
  186.  
  187.     // notify parent
  188.     PostMessage(GetParent(hwnd),
  189.                 WM_COMMAND,
  190.                 MAKEWPARAM((WORD)GetWindowLong(hwnd, GWL_ID), PCN_CHANGE),
  191.                 (LPARAM)hwnd);
  192.  
  193.     return 0;
  194. }
  195.  
  196.  
  197. //
  198. //  FUNCTION: MsgPalCtrlPaint(HWND, UINT, WPARAM, LPARAM)
  199. //
  200. //  PURPOSE: 
  201. //
  202. //  PARAMETERS:
  203. //
  204. //    hwnd      - Window handle  (Unused)
  205. //    uMessage  - Message number (Unused)
  206. //    wparam    - Extra data     (Unused)
  207. //    lparam    - Extra data     (Unused)
  208. //
  209. //  RETURN VALUE:
  210. //
  211. //    Always returns 0 - Message handled
  212. //
  213. //  COMMENTS:
  214. //
  215.  
  216. #pragma argsused
  217. LRESULT MsgPalCtrlPaint(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  218. {
  219.      RECT          rect;
  220.      HDC           hDC;
  221.      PAINTSTRUCT   ps;
  222.     int           nCols;
  223.      int           nColors, i;
  224.      int           cxSquare, cySquare;
  225.      HPALETTE      hPal, hOldPal;
  226.     HANDLE        hPalCtrlInfo;
  227.     LPPALCTRLINFO lpPalCtrlInfo;
  228.     int           nCurrent;
  229.  
  230.     // First do some setup.
  231.  
  232.     GetClientRect(hwnd, &rect);
  233.  
  234.     hDC      = BeginPaint(hwnd, &ps);
  235.     hPalCtrlInfo = (HANDLE)GetWindowLong(hwnd, WL_PAL_HPALCTRLINFO);
  236.  
  237.     if (!hPalCtrlInfo)
  238.         goto ENDPAINT;
  239.  
  240.     lpPalCtrlInfo = (LPPALCTRLINFO)GlobalLock(hPalCtrlInfo);
  241.     hPal          = lpPalCtrlInfo->hPal;
  242.     nColors       = lpPalCtrlInfo->nEntries;
  243.     cxSquare      = lpPalCtrlInfo->cxSquare;
  244.     cySquare      = lpPalCtrlInfo->cySquare;
  245.      nCurrent      = lpPalCtrlInfo->nEntry;
  246.     nCols         = lpPalCtrlInfo->nCols;
  247.     GlobalUnlock(hPalCtrlInfo);
  248.  
  249.     // Let's paint -- first realize the palette.  Note that
  250.     //  we ALWAYS realize the palette as if it were a background
  251.     //  palette (i.e. the last parm is TRUE).  We do this, since
  252.     //  we will already be the foreground palette if we are
  253.     //  supposed to be (because we handle the WM_QUERYNEWPALETTE
  254.     //  message).
  255.     if (hPal)
  256.         hOldPal = SelectPalette(hDC, hPal, TRUE);
  257.      else
  258.         goto ENDPAINT;
  259.  
  260.     RealizePalette(hDC);
  261.  
  262.     // Go through the palette displaying each color
  263.     //  as a rectangle.
  264.     for (i = 0;  i < nColors;  i++)
  265.     {
  266.         HBRUSH hBrush, hOldBrush;
  267.  
  268.         hBrush = CreateSolidBrush(PALETTEINDEX(i));
  269.           if (hBrush)
  270.         {
  271.             POINT pt;
  272.  
  273.             hOldBrush = SelectObject(hDC, hBrush);
  274.  
  275.             pt.x = (i % nCols) * cxSquare;
  276.             pt.y = (i / nCols) * cySquare;
  277.  
  278.             Rectangle(hDC,
  279.                       pt.x,
  280.                       pt.y,
  281.                              pt.x + cxSquare,
  282.                       pt.y + cySquare);
  283.  
  284.             SelectObject(hDC, hOldBrush);
  285.             DeleteObject(hBrush);
  286.         }
  287.     }
  288.  
  289.     // Highlight the currently selected palette square
  290.     HighlightSquare(hDC, 
  291.                     hPal, 
  292.                     nCurrent,
  293.                           cxSquare,
  294.                     cySquare, 
  295.                     nCols,
  296.                     nColors);
  297.  
  298.     // Clean up.
  299.     if (hOldPal)
  300.         SelectPalette(hDC, hOldPal, FALSE);
  301.  
  302. ENDPAINT:
  303.     EndPaint(hwnd, &ps);
  304.     
  305.      return 0;
  306. }
  307.  
  308.  
  309. //
  310. //  FUNCTION: MsgPalCtrlLButtonDown(HWND, UINT, WPARAM, LPARAM)
  311. //
  312. //  PURPOSE:  Process WM_LBUTTONDOWN messages by performing hit-testing
  313. //            on the color grid to see which color is selected by the user.
  314. //
  315. //  PARAMETERS:
  316. //
  317. //    hwnd      - Window handle  (Unused)
  318. //    uMessage  - Message number (Unused)
  319. //    wparam    - Extra data     (Unused)
  320. //    lparam    - Extra data     (Unused)
  321. //
  322. //  RETURN VALUE:
  323. //
  324. //    Always returns 0 - Message handled
  325. //
  326. //  COMMENTS:
  327. //
  328.  
  329. #pragma argsused
  330. LRESULT MsgPalCtrlLButtonDown(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  331. {
  332.     HDC           hDC;
  333.     HANDLE        hPalCtrlInfo;
  334.     LPPALCTRLINFO lpPalCtrlInfo;
  335.     int           nRow, nCol;
  336.  
  337.     hPalCtrlInfo = (HANDLE)GetWindowLong(hwnd, WL_PAL_HPALCTRLINFO);
  338.     if (!hPalCtrlInfo)
  339.         return 0;
  340.  
  341.     lpPalCtrlInfo = (LPPALCTRLINFO)GlobalLock(hPalCtrlInfo);
  342.     nRow          = (HIWORD(lparam)) / lpPalCtrlInfo->cySquare;
  343.      nCol          = LOWORD(lparam) / lpPalCtrlInfo->cxSquare;
  344.     hDC           = GetDC(hwnd);
  345.  
  346.     // Determine which entry is the new highlighted entry.
  347.     // Since our actual palette grid may not fill the entire
  348.     // control, check that we're really clicking in the palette
  349.     // gris and not just in the control client area...
  350.     if (nCol < 16)
  351.         if ((nRow * lpPalCtrlInfo->nCols + nCol) < lpPalCtrlInfo->nEntries)
  352.         {
  353.             UnHighlightSquare(hDC, 
  354.                               lpPalCtrlInfo->nEntry, 
  355.                                         lpPalCtrlInfo->cxSquare,
  356.                               lpPalCtrlInfo->cySquare,
  357.                               lpPalCtrlInfo->nCols);
  358.  
  359.             lpPalCtrlInfo->nEntry = nRow * lpPalCtrlInfo->nCols + nCol;
  360.         
  361.             HighlightSquare(hDC,
  362.                             lpPalCtrlInfo->hPal, 
  363.                             lpPalCtrlInfo->nEntry,
  364.                             lpPalCtrlInfo->cxSquare, 
  365.                             lpPalCtrlInfo->cySquare, 
  366.                             lpPalCtrlInfo->nCols,
  367.                                      lpPalCtrlInfo->nEntries);
  368.         
  369.             // notify parent
  370.             PostMessage(GetParent(hwnd),
  371.                         WM_COMMAND,
  372.                         MAKEWPARAM((WORD)GetWindowLong(hwnd, GWL_ID),
  373.                                    PCN_CHANGE),
  374.                         (LPARAM)hwnd);
  375.         }
  376.  
  377.     ReleaseDC(hwnd, hDC);
  378.     GlobalUnlock(hPalCtrlInfo);
  379.  
  380.     return 0;
  381. }
  382.  
  383.  
  384. //
  385. //  FUNCTION: MsgPalCtrlLButtonDblClk(HWND, UINT, WPARAM, LPARAM)
  386. //
  387. //  PURPOSE:  Process WM_LBUTTONDBLCLK messages by sending WM_COMMAND IDOK
  388. //            to the parent window.
  389. //
  390. //  PARAMETERS:
  391. //
  392. //    hwnd      - Window handle  (Unused)
  393. //    uMessage  - Message number (Unused)
  394. //    wparam    - Extra data     (Unused)
  395. //    lparam    - Extra data     (Unused)
  396. //
  397. //  RETURN VALUE:
  398. //
  399. //    Always returns 0 - Message handled
  400. //
  401. //  COMMENTS:
  402. //
  403.  
  404. #pragma argsused
  405. LRESULT MsgPalCtrlLButtonDblClk(HWND   hwnd,
  406.                                 UINT   uMessage,
  407.                                 WPARAM wparam,
  408.                                 LPARAM lparam)
  409. {
  410.     // send IDOK to parent window
  411.     PostMessage(GetParent(hwnd),
  412.                 WM_COMMAND,
  413.                 MAKEWPARAM(IDOK, (WORD)GetWindowLong(hwnd, GWL_ID)),
  414.                      (LPARAM)hwnd);
  415.  
  416.     return 0;
  417. }
  418.  
  419.  
  420. //
  421. //  FUNCTION: MsgPalCtrlGetDlgCode(HWND, UINT, WPARAM, LPARAM)
  422. //
  423. //  PURPOSE:  Process WM_GETDLGCODE in order for PalCtrl to receive input
  424. //            for the arrow keys.
  425. //
  426. //  PARAMETERS:
  427. //
  428. //    hwnd      - Window handle  (Unused)
  429. //    uMessage  - Message number (Unused)
  430. //    wparam    - Extra data     (Unused)
  431. //    lparam    - Extra data     (Unused)
  432. //
  433. //  RETURN VALUE:
  434. //
  435. //    Returns DLGC_WANTARROWS
  436. //
  437. //  COMMENTS:
  438. //
  439.  
  440. #pragma argsused
  441. LRESULT MsgPalCtrlGetDlgCode(HWND   hwnd,
  442.                                       UINT   uMessage,
  443.                                       WPARAM wparam,
  444.                              LPARAM lparam)
  445. {
  446.     return DLGC_WANTARROWS;
  447. }
  448.  
  449.  
  450. //
  451. //  FUNCTION: MsgPalCtrlKeyDown(HWND, UINT, WPARAM, LPARAM)
  452. //
  453. //  PURPOSE:  Process WM_KEYDOWN messages by changing the selected color
  454. //            accordingly.
  455. //
  456. //  PARAMETERS:
  457. //
  458. //    hwnd      - Window handle  (Unused)
  459. //    uMessage  - Message number (Unused)
  460. //    wparam    - Extra data     (Unused)
  461. //    lparam    - Extra data     (Unused)
  462. //
  463. //  RETURN VALUE:
  464. //
  465. //    Always returns 0 - Message handled
  466. //
  467. //  COMMENTS:
  468. //
  469.  
  470. #pragma argsused
  471. LRESULT MsgPalCtrlKeyDown(HWND   hwnd,
  472.                           UINT   uMessage,
  473.                           WPARAM wparam,
  474.                           LPARAM lparam)
  475. {
  476.     HDC           hDC;
  477.     HANDLE        hPalCtrlInfo;
  478.     LPPALCTRLINFO lpPalCtrlInfo;
  479.     int           nEntry, nMaxEntry;
  480.     int           nCol;
  481.  
  482.     hPalCtrlInfo = (HANDLE)GetWindowLong(hwnd, WL_PAL_HPALCTRLINFO);
  483.     if (!hPalCtrlInfo)
  484.         return 0;
  485.  
  486.     lpPalCtrlInfo = (LPPALCTRLINFO)GlobalLock(hPalCtrlInfo);
  487.     
  488.     nEntry    = lpPalCtrlInfo->nEntry;
  489.     nMaxEntry = lpPalCtrlInfo->nEntries - 1;
  490.     nCol      = lpPalCtrlInfo->nCols;
  491.  
  492.     switch (wparam)
  493.     {
  494.         case VK_LEFT:
  495.                 if ((nEntry - 1) <= 0)
  496.                 nEntry = 0;
  497.             else
  498.                 nEntry--;
  499.             goto UpdateSelection;
  500.  
  501.           case VK_RIGHT:
  502.                 if ((nEntry + 1) >= nMaxEntry)
  503.                      nEntry = nMaxEntry;
  504.                 else
  505.                      nEntry++;
  506.                 goto UpdateSelection;
  507.  
  508.           case VK_UP:
  509.                 if ((nEntry - nCol) >= 0)
  510.                      nEntry -= nCol;
  511.                 goto UpdateSelection;
  512.  
  513.           case VK_DOWN:
  514.                 if ((nEntry + nCol) <= nMaxEntry)
  515.                      nEntry += nCol;
  516.  
  517. UpdateSelection:
  518.                 if (nEntry != lpPalCtrlInfo->nEntry)
  519.                 {
  520.                      hDC = GetDC(hwnd);
  521.  
  522.                      UnHighlightSquare(hDC,
  523.                                              lpPalCtrlInfo->nEntry,
  524.                                              lpPalCtrlInfo->cxSquare,
  525.                                              lpPalCtrlInfo->cySquare,
  526.                                              lpPalCtrlInfo->nCols);
  527.  
  528.                      lpPalCtrlInfo->nEntry = nEntry;
  529.  
  530.                      HighlightSquare(hDC,
  531.                                           lpPalCtrlInfo->hPal,
  532.                                           lpPalCtrlInfo->nEntry,
  533.                                           lpPalCtrlInfo->cxSquare,
  534.                                           lpPalCtrlInfo->cySquare,
  535.                                           lpPalCtrlInfo->nCols,
  536.                                           lpPalCtrlInfo->nEntries);
  537.         
  538.                 // notify parent
  539.                 PostMessage(GetParent(hwnd),
  540.                             WM_COMMAND,
  541.                             MAKEWPARAM((WORD)GetWindowLong(hwnd, GWL_ID),
  542.                                        PCN_CHANGE),
  543.                             (LPARAM)hwnd);
  544.             
  545.                 ReleaseDC(hwnd, hDC);
  546.             }
  547.             break;
  548.  
  549.         default:
  550.             break;
  551.     }
  552.  
  553.     GlobalUnlock(hPalCtrlInfo);
  554.  
  555.     return 0;
  556. }
  557.  
  558.  
  559. //
  560. //  FUNCTION: MsgPalCtrlDestroy(HWND, UINT, WPARAM, LPARAM)
  561. //
  562. //  PURPOSE: Calls PostQuitMessage().
  563. //
  564. //  PARAMETERS:
  565. //
  566. //    hwnd      - Window handle  (Unused)
  567. //    uMessage  - Message number (Unused)
  568. //    wparam    - Extra data     (Unused)
  569. //    lparam    - Extra data     (Unused)
  570. //
  571. //  RETURN VALUE:
  572. //
  573. //    Always returns 0 - Message handled
  574. //
  575. //  COMMENTS:
  576. //
  577.  
  578. #pragma argsused
  579. LRESULT MsgPalCtrlDestroy(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  580. {
  581.      HANDLE    hPalCtrlInfo;
  582.      LPPALCTRLINFO lpPalCtrlInfo;
  583.  
  584.      hPalCtrlInfo = (HANDLE)GetWindowLong(hwnd, WL_PAL_HPALCTRLINFO);
  585.      if (!hPalCtrlInfo)
  586.           return 0;
  587.  
  588.      lpPalCtrlInfo = (LPPALCTRLINFO)GlobalLock(hPalCtrlInfo);
  589.  
  590.     if (lpPalCtrlInfo->hPal)
  591.         DeleteObject(lpPalCtrlInfo->hPal);
  592.  
  593.     GlobalUnlock(hPalCtrlInfo);
  594.     GlobalFree(hPalCtrlInfo);
  595.     SetWindowLong(hwnd, WL_PAL_HPALCTRLINFO, 0);
  596.     
  597.      return 0;
  598. }
  599.  
  600.  
  601. //
  602. //  FUNCTION: MsgPalCtrlGetCurSel(HWND, UINT, WPARAM, LPARAM)
  603. //
  604. //  PURPOSE: Fills in PALINFO structure with index and RGB values
  605. //
  606. //  PARAMETERS:
  607. //
  608. //    hwnd      - Window handle of PalCtrl
  609. //    uMessage  - Message number (Unused)
  610. //    wparam    - Extra data     (Unused)
  611. //    lparam    - Pointer to a PALINFO structure
  612. //
  613. //  RETURN VALUE:
  614. //
  615. //    Always returns 0 - Message handled
  616. //
  617. //  COMMENTS:
  618. //
  619.  
  620. #pragma argsused
  621. LRESULT MsgPalCtrlGetCurSel(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  622. {
  623.      HANDLE        hPalCtrlInfo;
  624.      LPPALCTRLINFO lpPalCtrlInfo;
  625.      HDC           hdc;
  626.     HPALETTE      hOldPal;
  627.     COLORREF      crColor;
  628.  
  629.     hPalCtrlInfo = (HANDLE)GetWindowLong(hwnd, WL_PAL_HPALCTRLINFO);
  630.     if (!hPalCtrlInfo)
  631.         return 0;
  632.     
  633.     lpPalCtrlInfo = (LPPALCTRLINFO)GlobalLock(hPalCtrlInfo);
  634.  
  635.     hdc     = GetDC(hwnd);
  636.     hOldPal = SelectPalette(hdc, lpPalCtrlInfo->hPal, TRUE);
  637.      RealizePalette(hdc);
  638.     crColor = GetNearestColor(hdc, PALETTEINDEX(lpPalCtrlInfo->nEntry));
  639.  
  640.     // fill in info
  641.     ((LPPALINFO)lparam)->index = lpPalCtrlInfo->nEntry;
  642.     ((LPPALINFO)lparam)->red   = GetRValue(crColor);
  643.     ((LPPALINFO)lparam)->green = GetGValue(crColor);
  644.     ((LPPALINFO)lparam)->blue  = GetBValue(crColor);
  645.  
  646.     SelectPalette(hdc, hOldPal, TRUE);
  647.     ReleaseDC(hwnd, hdc);
  648.     GlobalUnlock(hPalCtrlInfo);
  649.  
  650.     return 0;
  651. }
  652.  
  653.  
  654. //
  655. //  FUNCTION: MsgPalCtrlGetCurSel(HWND, UINT, WPARAM, LPARAM)
  656. //
  657. //  PURPOSE: Sets selected color for the PalCtrl
  658. //
  659. //  PARAMETERS:
  660. //
  661. //    hwnd      - Window handle  (Unused)
  662. //    uMessage  - Message number (Unused)
  663. //    wparam    - Extra data     (Unused)
  664. //    lparam    - Contains desired index to be selected
  665. //
  666. //  RETURN VALUE:
  667. //
  668. //    Always returns 0 - Message handled
  669. //
  670. //  COMMENTS:
  671. //
  672.  
  673. #pragma argsused
  674. LRESULT MsgPalCtrlSetCurSel(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  675. {
  676.     HANDLE        hPalCtrlInfo;
  677.     LPPALCTRLINFO lpPalCtrlInfo;
  678.     HDC           hDC;
  679.  
  680.     hPalCtrlInfo = (HANDLE)GetWindowLong(hwnd, WL_PAL_HPALCTRLINFO);
  681.     if (!hPalCtrlInfo)
  682.         return 0;
  683.     lpPalCtrlInfo = (LPPALCTRLINFO)GlobalLock(hPalCtrlInfo);
  684.  
  685.     // store selected index
  686.     lpPalCtrlInfo->nEntry = (int)lparam;
  687.  
  688.     hDC = GetDC(hwnd);
  689.  
  690.     // Highlight the specified palette square
  691.     HighlightSquare(hDC,
  692.                     lpPalCtrlInfo->hPal,
  693.                     lpPalCtrlInfo->nEntry,
  694.                     lpPalCtrlInfo->cxSquare,
  695.                     lpPalCtrlInfo->cySquare,
  696.                           lpPalCtrlInfo->nCols,
  697.                     lpPalCtrlInfo->nEntries);
  698.  
  699.     ReleaseDC(hwnd, hDC);
  700.     
  701.     // notify parent so appropriate updating occurs
  702.     PostMessage(GetParent(hwnd),
  703.                 WM_COMMAND,
  704.                 MAKEWPARAM((WORD)GetWindowLong(hwnd, GWL_ID),
  705.                            PCN_CHANGE),
  706.                 (LPARAM)hwnd);
  707.  
  708.      GlobalUnlock(hPalCtrlInfo);
  709.  
  710.     return 0;
  711. }
  712.  
  713.  
  714. //
  715. //  FUNCTION: HighlightSquare(HDC, HPALETTE, int, int, int, int, int)
  716. //
  717. //  PURPOSE:  Highlight the currently selected palette entry and
  718. //            change the info bar to reflect it.
  719. //
  720. //  PARAMETERS:
  721. //    hDC       - DC where we want to highlight a pal. square.
  722. //    hPal      - Handle to the palette we're displaying info on.
  723. //    nEntry    - Entry to highlight.
  724. //    cxSquare  - Width a a palette square.
  725. //    cySquare  - Height of a palette square.
  726. //    nCols     - # of columns currently displayed in window.
  727. //    nColors   - # of colors in the palette.
  728. //
  729. //  RETURN VALUE:
  730. //    None.
  731. //
  732. //  COMMENTS:
  733. //
  734.  
  735. #pragma argsused
  736. void HighlightSquare(HDC hDC, 
  737.                             HPALETTE hPal,
  738.                             int nEntry,
  739.                      int cxSquare, 
  740.                      int cySquare, 
  741.                      int nCols,
  742.                      int nColors)
  743. {
  744.     RECT         rect;
  745.     HBRUSH       hBrush;
  746.     PALETTEENTRY pe;
  747.  
  748.     rect.left   = (nEntry % nCols) * cxSquare;
  749.     rect.top    = (nEntry / nCols) * cySquare;
  750.      rect.right  = rect.left + cxSquare;
  751.     rect.bottom = rect.top  + cySquare;
  752.     hBrush      = CreateHatchBrush(HS_BDIAGONAL,
  753.                                    GetSysColor(COLOR_HIGHLIGHT));
  754.  
  755.     FrameRect(hDC, &rect, hBrush);
  756.  
  757.     GetPaletteEntries(hPal, nEntry, 1, &pe);
  758.  
  759.     // If the palette entry we just got is just an index into the
  760.     //  system palette, get it's RGB value.
  761.  
  762.      if (pe.peFlags == PC_EXPLICIT)
  763.     {
  764.         COLORREF cref;
  765.         HPALETTE hOldPal;
  766.  
  767.         cref       = PALETTEINDEX((WORD)pe.peRed + (pe.peGreen << 4));
  768.         hOldPal    = SelectPalette(hDC, hPal, FALSE);
  769.         cref       = GetNearestColor(hDC, cref);
  770.         pe.peRed   = (BYTE)  (cref & 0x0000FF);
  771.         pe.peGreen = (BYTE) ((cref & 0x00FF00) >> 8);
  772.         pe.peBlue  = (BYTE) ((cref & 0xFF0000) >> 16);  
  773.  
  774.           SelectPalette(hDC, hOldPal, FALSE);
  775.     }
  776.  
  777.     DeleteObject(hBrush);
  778. }
  779.  
  780. //
  781. //  FUNCTION: UnHighlightSquare(HDC, int, int, int, int)
  782. //
  783. //  PURPOSE:  Un-highlight a palette entry.
  784. //
  785. //  PARAMETERS:
  786. //    hDC       - DC where we want to unhighlight a pal. square.
  787. //    nEntry    - Entry to highlight.
  788. //    cxSquare  - Width a a palette square.
  789. //    cySquare  - Height of a palette square.
  790. //    nCols     - # of columns currently displayed in window.
  791. //
  792. //  RETURN VALUE:
  793. //    None.
  794. //
  795. //  COMMENTS:
  796. //
  797.  
  798. void UnHighlightSquare(HDC hDC, 
  799.                        int nEntry, 
  800.                        int cxSquare, 
  801.                        int cySquare,
  802.                        int nCols)
  803. {
  804.     RECT rect;
  805.  
  806.     rect.left   = (nEntry % nCols) * cxSquare;
  807.     rect.top    = (nEntry / nCols) * cySquare;
  808.     rect.right  = rect.left + cxSquare;
  809.     rect.bottom = rect.top  + cySquare;
  810.  
  811.     FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
  812. }
  813.  
  814.  
  815. //
  816. //  FUNCTION: SetPalCtrlPalette(HWND, HPALETTE)
  817. //
  818. //  PURPOSE:  Set a palette control's hPal in its PALCTRLINFO structure.
  819. //            This sets the palette that will be displayed in the
  820. //            given window.  Also sets up the number of color entries
  821. //            field in the PALCTRLINFO structure.
  822. //
  823. //  PARAMETERS:
  824. //
  825. //    hWnd      - Window we're going to display palette in.
  826. //    hPal      - Palette to display in the window.
  827. //
  828. //  RETURN VALUE:
  829. //
  830. //    None.
  831. //
  832. //  COMMENTS:
  833. //
  834.  
  835. void SetPalCtrlPalette(HWND hWnd, HPALETTE hPal)
  836. {
  837.     HANDLE    hPalCtrlInfo;
  838.     LPPALCTRLINFO lpPalCtrlInfo;
  839.  
  840.     if (!hPal)
  841.         return;
  842.  
  843.     hPalCtrlInfo = (HANDLE)GetWindowLong(hWnd, WL_PAL_HPALCTRLINFO);
  844.  
  845.     if (hPalCtrlInfo)
  846.     {
  847.         lpPalCtrlInfo           = (LPPALCTRLINFO)GlobalLock(hPalCtrlInfo);
  848.         lpPalCtrlInfo->hPal     = hPal;
  849.         lpPalCtrlInfo->nEntries = ColorsInPalette(hPal);
  850.  
  851.         GlobalUnlock(hPalCtrlInfo);
  852.     }
  853. }
  854.